package com.wx.commons;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.wx.core.process.HttpMethod;
import com.wx.core.process.WxApi;
import com.wx.core.vo.request.FansBatchGet;
import com.wx.core.vo.response.Fans;
import com.wx.entity.WxFansUser;
import com.wx.service.SysWxuserService;
import com.wx.service.WxFansUserService;
import com.zyht.common.util.HttpUtils;
import com.zyht.common.util.Page;
import com.zyht.common.util.SpecialCharacterFilterUtil;
public class SyncFansThread extends Thread{
	
	private static final Logger logger = LoggerFactory.getLogger(SyncFansThread.class);
	
	private WxFansUserService wxFansUserService;
	private SysWxuserService sysWxuserService;
	private String wxid;  
	private int uid;
	private String accessToken;
	private int count;//计数,表示更新了多少个数据
	private int total;
	
	@Override
	public void run() {
		int fancount = 0;
		//设置最高取粉丝5W条
		int times = 5;
		String nextOpenId = null;
		do {
			String requestUrl = WxApi.getFansListUrl(accessToken, nextOpenId);
			String result = HttpUtils.httpsGet(requestUrl);
			JSONObject jSONObject = JSONObject.parseObject(result);
			if (isOk(jSONObject)) {
				fancount = jSONObject.getInteger("count");
				// 同步用户开始,批量同步一次支持100个查询
				if (fancount > 0) {
					if(times == 5)//仅作一次更新，更新微信主账号 粉丝数量
					nextOpenId = this.UpdateFans(jSONObject);
				}
				times--;
			} else
				break;
		} while (fancount >= 10000 && times > 0);
		
	}
	
	/**
	* @author: shanyz
	* @date:   2015年8月3日
	* @Title:  UpdateFans
	* @Description: 更新并返回最后一条的openid
	* @param @param jSONObject    设定文件
	* @return void    返回类型
	* @throws
	*/ 
	public String UpdateFans(JSONObject jSONObject){
		List<WxFansUser> dbList = wxFansUserService.selectByWxid(wxid);
		String lastOpenid = null;
		JSONArray openids = jSONObject.getJSONObject("data").getJSONArray("openid");
		Page<FansBatchGet> pages = new  Page<FansBatchGet>(jSONObject.getInteger("count"), 1, 100);
		for (int i = 1; i <= pages.getPages(); i++) {//分页更新 增加的数据和变动的数据
			//生成请求JSON	
			pages = new  Page<FansBatchGet>(jSONObject.getInteger("count"), i, 100);
			ArrayList<FansBatchGet> reqList = new ArrayList<FansBatchGet>();
			for (int j = pages.getStart(); j < pages.getEnd(); j++) {
				FansBatchGet fansBatchGet = new FansBatchGet();
				fansBatchGet.setOpenid(openids.getString(j));
				fansBatchGet.setLang("zh-CN");
				reqList.add(fansBatchGet);
			}
			HashMap<String,ArrayList<FansBatchGet>> reqMap = new HashMap<String,ArrayList<FansBatchGet>>();
			reqMap.put("user_list", reqList);
			String requestUrl = WxApi.getRequestUrl(WxApi.GET_BATCH_FANS,accessToken);
			String  requestStr = HttpUtils.sendHttpsRequest(requestUrl,HttpMethod.GET, new Gson().toJson(reqMap));
			if(requestStr != null){
				//获取 user_info_list下的数据 gson
			    JsonParser jsonParser = new JsonParser();
			    JsonElement element = jsonParser.parse(requestStr);
			    JsonObject jsonObj = element.getAsJsonObject();
				 //fastjson 转换为集合对象
				ArrayList<Fans> list = (ArrayList<Fans>)JSON.parseArray(jsonObj.get("user_info_list").toString(), Fans.class);
				
				this.syncFans(dbList,list);
				//得到最后一个OPENID
				if(i == pages.getPages())
					lastOpenid = list.get(list.size()-1).getOpenid();
			}
		}
		//更新取消关注的数据删除 数据
/*		for (WxFansUser wxFansUser : dbList) {
			if(!openids.contains(wxFansUser.getOpenid())){
				wxFansUserService.deleteByPrimaryKey(wxFansUser.getId());
			}
		}*/
		return lastOpenid;
	}
	/**
	* @author: shanyz
	* @date:   2015年8月3日
	* @Title:  syncFans
	* @Description: 比较同步粉丝
	* @param @param list    设定文件
	* @return void    返回类型
	* @throws
	*/ 
	public void syncFans(List<WxFansUser> dbList , ArrayList<Fans> list){
		HashMap<String,WxFansUser> dbmap = this.getDbMap(dbList);
		for (Fans fans : list) {
			// 取消关注的不同步
			if (fans.getSubscribe() != null && fans.getSubscribe() == 0){
				WxFansUser wxFansUser = wxFansUserService.selectByOpenId(fans.getOpenid());
				if (wxFansUser != null) {
					wxFansUser.setSubscribe(0);
					wxFansUserService.updateByPrimaryKey(wxFansUser); 
				}
				continue;
			}
				
			//如果存在则比较差异更新数据
			if(dbmap.containsKey(fans.getOpenid()) && compareDb(fans,dbmap.get(fans.getOpenid()))){
				wxFansUserService.updateByPrimaryKey(dbmap.get(fans.getOpenid()));
			}
			//不存 在则插入新数据
			if(!dbmap.containsKey(fans.getOpenid())){
				try {
					wxFansUserService.insert(this.constructDbFans(fans));
				} catch (Exception e) {
					e.printStackTrace();
					logger.error("异常：count"+count+fans.getNickname() + "--" + fans.getGroupid()
							+ "---" + fans.getSex() + "--"
							+ fans.getSubscribe_time());
				}
			}
			count ++;
		}
		
	}
	public HashMap<String,WxFansUser> getDbMap(List<WxFansUser> list){
		HashMap<String,WxFansUser> map = new HashMap<String,WxFansUser>();
		for (WxFansUser wxFansUser : list) {
			map.put(wxFansUser.getOpenid(), wxFansUser);
		}
		return map;
	}
	public HashMap<String,Fans> changeWxMap(List<Fans> list){
		HashMap<String,Fans> map = new HashMap<String,Fans>();
		for (Fans fans : list) {
			map.put(fans.getOpenid(), fans);
		}
		return map;
	}
	public WxFansUser constructDbFans(Fans fans){
		WxFansUser f = new WxFansUser();
		BeanUtils.copyProperties(fans, f);
		if (fans.getNickname() != null)
			f.setNickname(SpecialCharacterFilterUtil.utf8ToUnicode(fans
					.getNickname()));
		if (fans.getSubscribe_time() != null)
			f.setSubscribeTime(new Date(fans.getSubscribe_time() * 1000L));
		else
			f.setSubscribeTime(new Date());
		if(f.getSex() == null)
			f.setSex(0);
		if(f.getLanguage() == null)
			f.setLanguage("zh_CN");
		if(f.getGroupid() == null)
			f.setGroupid(0);
		f.setUid(uid);
		f.setWxid(wxid);
		return f;
	}
	/**
	* @author: shanyz
	* @date:   2015年8月3日
	* @Title:  compareDb
	* @Description: 比较接口 与数据库中不同属性
	* @param @param wx
	* @param @param db
	* @param @return    设定文件
	* @return boolean    返回类型
	* @throws
	*/ 
	public boolean compareDb(Fans wx,WxFansUser db){
		boolean bool = false;
		
		//存在了nickname为空的，如果关注了，数据库nickname为空 则更新一下
		if(wx.getSubscribe()==1 && db.getNickname() == null){
			db.setHeadimgurl(wx.getHeadimgurl());
			db.setNickname(SpecialCharacterFilterUtil.utf8ToUnicode(wx.getNickname()));
			db.setSex(wx.getSex());
			db.setGroupid(wx.getGroupid());
			return true;
		}
		
		if(wx.getHeadimgurl()!=null && db.getHeadimgurl()!=null && !db.getHeadimgurl().equals(wx.getHeadimgurl())){
			db.setHeadimgurl(wx.getHeadimgurl());
			bool = true;
		}
		if(wx.getNickname()!=null && db.getNickname()!=null && ! SpecialCharacterFilterUtil.utf8ToUnicode(db.getNickname()).equals(wx.getNickname())){
			db.setNickname(SpecialCharacterFilterUtil.utf8ToUnicode(wx.getNickname()));
			bool = true;
		}
		if(wx.getSex()!=null && db.getSex()!=null && db.getSex().intValue() != wx.getSex().intValue()){
			db.setSex(wx.getSex());
			bool = true;
		}
		if(wx.getGroupid()!=null && db.getGroupid()!=null && db.getGroupid().intValue() != wx.getGroupid().intValue()){
			db.setGroupid(wx.getGroupid());
			bool = true;
		}
			
		return bool;
	}
	public String getAccessToken() {
		return accessToken; 
	}

	public void setAccessToken(String accessToken) {
		this.accessToken = accessToken;
	}

	public int getCount() {
		return count;
	}

	public void setCount(int count) {
		this.count = count;
	}

	public WxFansUserService getWxFansUserService() {
		return wxFansUserService;
	}
	public void setWxFansUserService(WxFansUserService wxFansUserService) {
		this.wxFansUserService = wxFansUserService;
	}
	public SysWxuserService getSysWxuserService() {
		return sysWxuserService;
	}
	public void setSysWxuserService(SysWxuserService sysWxuserService) {
		this.sysWxuserService = sysWxuserService;
	}
	public String getWxid() {
		return wxid;
	}
	public void setWxid(String wxid) {
		this.wxid = wxid;
	}
	public int getUid() {
		return uid;
	}
	public void setUid(int uid) {
		this.uid = uid;
	}
	public int getTotal() {
		return total;
	}
	public void setTotal(int total) {
		this.total = total;
	}

	private boolean isOk(JSONObject jSONObject){

		if(jSONObject.get("errcode") == null || jSONObject.get("errcode") == "0"){
			logger.error("******读取接口成功*********" + jSONObject.toString());
			return true;
		} else{
			logger.error("******微信接口错误*********" + jSONObject.toString());
			return false;
		}
	}
}
